perm filename TALK11.SAI[PNT,HE]3 blob sn#492443 filedate 1980-01-22 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	ENTRY
C00004 00003	!  PEEK, POKE, STRT11,PEEKARRAY, POKEARRAY
C00009 00004	!	check elf status and communication 
C00013 00005	!	routines that make console look like VT05
C00018 00006	!	alinit
C00020 00007	!	sav11,res11
C00022 ENDMK
C⊗;
ENTRY;
BEGIN
DEFINE $TALK11=TRUE;
REQUIRE "HEADER.SAI" SOURCE_FILE;

! DEFINE OUTTST = "OUTSTR";
  DEFINE OUTTST = "! ";


INTEGER ELFCHAN;  !  Channel number for I/O to ELF;

PROCEDURE COMERR
      (STRING MESSG;RECORD_POINTER(ANY_CLASS) CONTXT (NULL_RECORD));
        !  Non-fatal warnings;
        BEGIN
        USERERR(0,1,"HAH!  "&MESSG);
        END;

DEFINE SGNEXT="'4000000";	! extend sign bit of input data ;
DEFINE OWPW   ="0";		! word for word transfer;
DEFINE TWRJ   ="'1000000";	! two words per word,right justified in each halfword;
DEFINE TWRM   ="'2000000";	! two words per word,in right most 32 bits;
DEFINE TWLM   ="'3000000";	! two words per word,in left most 32 bits;


integer array ttmpbuf[1:fbuffsiz*2];

DEFINE ELFHIADDR="('500000)";
!  PEEK, POKE, STRT11,PEEKARRAY, POKEARRAY;
INTEGER MTAPE_PLUS_ELF;
DEFINE ELFMTAPE(ADDR)="CODE(MTAPE_PLUS_ELF,ADDR)";
! peek,poke and peekarray take the actual address on the unibus;

PROCEDURE FILL(INTEGER ADR(0),LEN(ELFHIADDR/2),CNTNTS(0));
    BEGIN "fill"
    INTEGER ARRAY A[1:2];
    DEFINE FILL = "'001000000000";
    A[1]←FILL+(ADR LSH -1);
    A[2]←(LEN LSH 18)+CNTNTS;
    ELFMTAPE(A[1]);
    IF NOT _SKIP_ THEN COMERR("Couldn't fill ELF with "&CVOS(CNTNTS));
    END;

INTERNAL INTEGER PROCEDURE PEEK(INTEGER ADR);
    BEGIN "peek"  !  Returns the ELF word at unibus address ADR;
    INTEGER ARRAY A[1:2];
    DEFINE PEEK = "'002000000000";
    A[1]←PEEK+(ADR LSH -1);
    !	   CALLU0("MTAPE",ELFCHAN,A[1]);
    ELFMTAPE(A[1]);
    IF NOT _SKIP_ THEN COMERR("Couldn't peek at ELF");
    RETURN(A[2]);
    END "peek";

PROCEDURE POKE(INTEGER ADR, CONTENTS);
    BEGIN "poke"  !  Stores CONTENTS at unibus address ADR;
    DEFINE POKE = "'003000000000";
    INTEGER ARRAY A[1:2];
    A[1]←POKE+(ADR LSH -1);
    A[2]←CONTENTS;
!   CALLU0("MTAPE",ELFCHAN,A[1]);
    ELFMTAPE(A[1]);
    IF NOT _SKIP_ THEN COMERR("Couldn't poke at ELF");
    END "poke";

PROCEDURE STRT11(INTEGER STRADR('1000));
    BEGIN "strt11"  !  Starts 11 at STRADR;
    DEFINE START = "'005000000000";
    INTEGER ARRAY A[1:2];
    INTEGER NOSTART;
    NOSTART←PEEK(NOSTRT);
    IF NOSTART THEN BEGIN
	POKE(NOSTRT,0); PRINT("Did not restart ELF");
	RETURN;
	END;
    A[1]←START;
    A[2]←0;
    POKE('24,STRADR);	! set starting address;
    POKE('26,'340);	! set priority level 7;
!   CALLU0("MTAPE",ELFCHAN,A[1]);
    ELFMTAPE(A[1]);
    IF NOT _SKIP_ THEN COMERR("Couldn't start ELF");
    CALL(5,"SLEEP");	! go sleep fro 5 seconds;
    END "strt11";

INTERNAL PROCEDURE POKEARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; INTEGER USETBITS(0));
    BEGIN "pokearray" !  Sends the CONTENTS[1:LTH] to unibus address ADR
		    and higher;
    INTEGER USETO_WORD,SNDIOWD;
    USETO_WORD←'400000400000 + (ADR LSH -1)+USETBITS;
    CALLU0("USETO",ELFCHAN,USETO_WORD);
    SNDIOWD←IOWD(LTH,LOCATION(CONTENTS[1]));
    CALLU0("OUT",ELFCHAN,SNDIOWD);
    IF _SKIP_ THEN COMERR("POKEARRAY failed");
    END "pokearray";

INTERNAL PROCEDURE PEEKARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; INTEGER USETBITS(0));
    BEGIN "peekarray" !  Gets the CONTENTS[1:LTH] from unibus address ADR
	    and higher;
    INTEGER USETI_WORD,GETIOWD;
    USETI_WORD←'400000400000 +(ADR LSH -1)+USETBITS;
    CALLU0("USETI",ELFCHAN,USETI_WORD);
    GETIOWD←IOWD(LTH,LOCATION(CONTENTS[1]));
    CALLU0("IN",ELFCHAN,GETIOWD);
    IF _SKIP_ THEN COMERR("PEEKARRAY failed");
    END "peekarray";
!	check elf status and communication ;
INTEGER PROCEDURE ELFSTATUS;
	BEGIN
	INTEGER I,STATUS;
	CHKESC_I;
	POKE(NOTB11,WAKEUP);
	FOR I←1 STEP 1 UNTIL 10 DO
		BEGIN
		URSCHD;
		CALL(0,"SLEEP");
		STATUS←PEEK(NOTB11);
		IF STATUS≠ASLEEP THEN RETURN(STATUS);
		END;
	RETURN(STATUS);
	END;

BOOLEAN ELF_ASLEEP_PRINTED;

INTEGER PROCEDURE LISTENELF;
	BEGIN
	INTEGER STATUS;
	$ELFABORTED←FALSE;
	STATUS←ELFSTATUS;
	IF STATUS≠ASLEEP THEN RETURN(STATUS);
	IF NOT ELF_ASLEEP_PRINTED THEN
		BEGIN
		PRINT("ELF is asleep, I will keep trying to wake it",CRLF,
			" till you type esc_I to abort",CRLF);
		ELF_ASLEEP_PRINTED←TRUE;
		END;
	DO BEGIN
		STATUS←ELFSTATUS;
		CHKESC_I;
	END UNTIL STATUS≠ASLEEP;
	RETURN(STATUS);
	END;

INTERNAL PROCEDURE EVAL(RPTR(EXPR$) EE);
	BEGIN
	INTEGER I,PSIZE;
	$PCDMAX←$PCDMAX MAX (PSIZE←EXPR$:#BODY[EE]);
	IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
	POKE(NOTB10,LISTEN);
	ELF_ASLEEP_PRINTED←FALSE;	! make sure print out error ;
	DO I←LISTENELF UNTIL I=LISTENING;
	IF PSIZE>PBUFFSIZ THEN
		ERROR("EVAL ERROR: statement pcode size too large");
	POKEARRAY(PCDBUF+MAP_OFFSET,PSIZE,EXPR$:BODY[EE]);
	POKE(NOTB10,WORK);
	DO IF (I←LISTENELF)=GAVEUP
		THEN BEGIN POKE(NOTB10,GOSLEEP);
			ERROR("abandoned this instruction midway");
		     END  UNTIL I=DONEWORKING;
	PEEKARRAY(NOTB11,8,NOTBOX);
	IF $INTSIZ←(INTPTR-INTBUF)/2 THEN
		BEGIN
		IF $INTSIZ<0 THEN ERROR("EVAL DISASTER: asking to transfer negative number of integers");
		IF $INTSIZ>IBUFFSIZ THEN
			ERROR("EVAL DISASTER: trying to transfer too many numbers; probably overran integer buffer");
		PEEKARRAY(INTBUF+MAP_OFFSET,INTSIZ,$INBUF,SGNEXT);
		END;
	IF $FPSIZ←(FPPTR-FPBUF)/4 THEN
		BEGIN
		IF $FPSIZ<0 THEN ERROR("EVAL DISASTER: asking to transfer negative number of FP nums");
		IF $FPSIZ>FBUFFSIZ THEN
			ERROR("EVAL DISASTER: trying to transfer too many numbers; probably overran FP buffer");
!		PEEKARRAY(FPBUF+MAP_OFFSET,FPSIZ,TMPBUF,TWLM);
		PEEKARRAY(FPBUF+MAP_OFFSET,$FPSIZ*2,TTMPBUF);
		FOR I←1 STEP 1 UNTIL $FPSIZ DO $FPBUF[I]←RFVAL(TTMPBUF[I*2-1],TTMPBUF[I*2]);
		END;
	POKE(NOTB10,GOSLEEP);
	$FPPTR←$INTPTR←0;
	$FPMAX←$FPMAX MAX $FPSIZ;
	$INTMAX←$INTMAX MAX $INTSIZ;
	END;
!	routines that make console look like VT05;

PRELOAD_WITH 30,'2000/35,'2000/24,'2000/36,'2000/30,'2000/30;
INTEGER ARRAY LINWIDTH[0:MAX_TTY];

SIMPLE INTEGER PROCEDURE YPOS(INTEGER LINE);
	RETURN('1000-LINE*LINWIDTH[$TTYTYPE]);

INTEGER ARRAY ADDR[0:'23];
SIMPLE INTEGER PROCEDURE LINEDPOS;
	BEGIN
	CALLU("PPINFO",ADDR[0]);
	RETURN(ADDR[2]LAND '777777);
	END;

DEFINE CONSOLE_PP="1";	! pp 1 for the output of elf ;
DEFINE CONSOLE_MODE=0,VT05_MODE←-1;
DEFINE ELF_OREG='274 ;
DEFINE ELF_IREG='272 ;
DEFINE OUTSW='270;
REQUIRE "SYS:PROCES.DEF" SOURCE_FILE;
BOOLEAN $ELFINT;
SIMPLE PROCEDURE INTELF;
	$ELFINT←TRUE;

ITEM READELF_ITEM,WRITEELF_ITEM,DUMMY_ITEM;
ITEMVAR MAINPR_ITEM;
REQUIRE 10 NEW_ITEMS;

PROCEDURE WRITEELF;
BEGIN	INTEGER CHAR,VAL;
	CHAR←0;
	WHILE TRUE DO
		BEGIN
		WHILE (VAL←PEEK(ELF_IREG))≠0 DO URSCHD;
		IF CHAR=CR THEN CHAR←INCHRW
		ELSE BEGIN
			WHILE (CHAR←INCHRS)<0 DO URSCHD;
			IF (CHAR LAND '200) THEN CHAR←CHAR LAND '77;
			POKE(ELF_IREG,CHAR);
			END
		END;
END;
DEFINE INTELF_INX=20;

PROCEDURE READELF;
BEGIN	INTEGER CHAR;
	WHILE TRUE DO
		BEGIN
		WHILE NOT $ELFINT DO URSCHD;
		POLL;
		$ELFINT←FALSE;
		ENABLE(INTELF_INX);
		CALLV("LEYPOS",LINEDPOS);
		CALLV("PPSEL",'400000+CONSOLE_PP);
		CHAR←PEEK(ELF_OREG);
		POKE(ELF_OREG,0);
		OUTCHR(CHAR);
		CALLV("PPSEL",'400000);
		END;
END;

PROCEDURE INIINTELF;
BEGIN
$ELFINT←FALSE;
intmap(INTELF_INX,INTELF,0);	! set mapping for interrupt handler for ELF;
enable(INTELF_INX);		! enable the interrupt handler;
END;

PROCEDURE ESCAPE_I;
BEGIN
	DO URSCHD UNTIL $ESC_I;
	TERMINATE(WRITEELF_ITEM);
	TERMINATE(READELF_ITEM);
	ENABLE(INTELF_INX);
	RESUME(MAINPR_ITEM,DUMMY_ITEM,KILLME);
END;

INTERNAL PROCEDURE CONSOLE;
BEGIN	! makes this a console for output of 11 ;
	MAINPR_ITEM←MYPROC;
	POKE(OUTSW,VT05_MODE);		! clean out vt05 mode;
	poke(elf_oreg,0);
	INIINTELF;
	POKE(OUTSW,CONSOLE_MODE);		! set to CONSOLE mode;
	CALLV("PPSEL",'400000+CONSOLE_PP);
	CALLV("DPYSIZ",15*'1000+1);	! 20 GLITCHES, 1 line per glitch ;
	CALLV("DPYPOS",YPOS(3));
	CALLV("PPACT",'400000 LOR ('400000 LSH -CONSOLE_PP));
	SCHEDULE_ON_CLOCK_INTERRUPTS;
	SPROUT(READELF_ITEM,READELF,RUNME);
	CALLV("PPSEL",'400000);
	CALLV("DPYPOS",YPOS(19));
	CALLV("LEYPOS",LINEDPOS);
END;

INTERNAL PROCEDURE UNCONSOLE;
BEGIN
	! change back to VT05;
	TERMINATE(READELF_ITEM);
	POKE(OUTSW,VT05_MODE);
	DISABLE(INTELF_INX);
	DISABLE(INTCLK_INX);
	CALLV("PPREL",CONSOLE_PP);
END;

INTERNAL PROCEDURE VT05;
BEGIN	INTEGER I;
	! accepts input from the terminal;
	IF PSTATUS(READELF_ITEM)=TERMINATED THEN CONSOLE;
	SPROUT(WRITEELF_ITEM,WRITEELF,RUNME);
	CALLV("LEYPOS",LINEDPOS);
	I←'11000000200;		! turn on noecho bit ;
	CALL(IOWD(1,LOCATION(I)+1),"TTYSET");
	CALLV("PPSEL",'400000+CONSOLE_PP);
	DO BEGIN URSCHD; CALL(1,"SLEEP"); END UNTIL $ESC_I;
	$ESC_I←FALSE; ENABLE(INTTTI_INX);
	CALLV("PPSEL",'400000);
	TERMINATE(WRITEELF_ITEM);
	I←'12000000200;		! turn off noecho bit ;
	CALL(IOWD(1,LOCATION(I)+1),"TTYSET");
END;
!	alinit;
INTERNAL PROCEDURE ALINIT;
    BEGIN "init" 
    INTEGER COUNT, BRCHAR, EOF, FLAG;
    INTEGER I;
	    !  Initialize the ELF for output;
	    !  '400 on in mode word  and EOF←1 to take silent return if not available;
    IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
    EOF←1;
    OPEN(ELFCHAN←GETCHAN,"ELF",'417,0,0,COUNT,BRCHAR,EOF);
    IF EOF THEN
	BEGIN PRINT("ELF is not available... I will just not do any i/o to ELF
"); $ELFUNAVAILABLE←TRUE; RETURN; END;
    ELF_ASLEEP_PRINTED←FALSE;
    MTAPE_PLUS_ELF←'072000000000+(ELFCHAN LSH 23);
    END "init";

!	sav11,res11;

INTERNAL PROCEDURE SAV11(INTEGER ARRAY MEM);
BEGIN
	INTEGER I;
	POKE(NOTB10,SAVE);
	CALL(1,"SLEEP");
	DO I←PEEK(NOTB11) UNTIL I=SAVED;
	CALL(2,"SLEEP");
	PEEKARRAY(0,ELFHIADDR/4,MEM,TWRJ);
END;

INTERNAL PROCEDURE RES11(INTEGER ARRAY MEM);
	IF NOT($NOELF OR $ELFUNAVAILABLE) THEN
		BEGIN
! commented out because cannot do packed mode write
		POKEARRAY(0,'500000/4,MEM,TWRJ);
		DEFINE BLKTRFR="(ELFHIADDR/(2*8))";! size of array transfer unpacked;
		DEFINE UBLKTRFR="BLKTRFR/2";	! size of array transfer packed;
		INTEGER ARRAY TEMP[1:BLKTRFR];
		INTEGER I,J,K;	! pointer to TEMP,MEM, and counter;
		STRT11('130000);	! start ddt to bring system to rest;
!		FILL;		! fill with zeroes ;
		J←0;
		FOR K←0 STEP 1 UNTIL 7
		    DO BEGIN
			FOR I←2 STEP 2 UNTIL BLKTRFR
				DO BEGIN
				   J←J+1;
				   TEMP[I-1]←(MEM[J] LSH -18) LAND '777777;
				   TEMP[I]←MEM[J] LAND '777777;
				END;
			POKEARRAY(K*BLKTRFR*2,BLKTRFR,TEMP);
			END;
		END;

INTERNAL PROCEDURE RESTRT11(INTEGER STRADR('1000));
BEGIN
	INTEGER I;
	IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
	POKE(SAILID,"P");
	POKE(OUTSW,VT05_MODE);
	STRT11(STRADR);
	DO I←LISTENELF UNTIL I=AWAKE;
	PEEKARRAY(NOTB11,8,NOTBOX);
END;

END;